package com.lhq.lingsi_study_hall.scoring;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lhq.lingsi_study_hall.model.dto.question.QuestionContentDTO;
import com.lhq.lingsi_study_hall.model.entity.App;
import com.lhq.lingsi_study_hall.model.entity.Question;
import com.lhq.lingsi_study_hall.model.entity.ScoringResult;
import com.lhq.lingsi_study_hall.model.entity.UserAnswer;
import com.lhq.lingsi_study_hall.model.vo.QuestionVO;
import com.lhq.lingsi_study_hall.service.QuestionService;
import com.lhq.lingsi_study_hall.service.ScoringResultService;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义测评类应用评分策略
 * 如：MBTI测试（没有标准的答案，最终的答案根据用户的所选项决定）
 */
@ScoringStrategyConfig(appType = 1, scoringStrategy = 0)
public class CustomTestScoringStrategy implements ScoringStrategy {
    @Resource
    private QuestionService questionService;
    @Resource
    private ScoringResultService scoringResultService;
    @Override
    public UserAnswer doScore(List<String> choices, App app) {
        //1. 根据id查询对应的题目和题目结果信息
        Long appId = app.getId();
        Question question = questionService.getOne(
                Wrappers.lambdaQuery(Question.class).eq(Question::getAppId, appId)
        );
        List<ScoringResult> scoringResultList = scoringResultService.list(
                Wrappers.lambdaQuery(ScoringResult.class).eq(ScoringResult::getAppId, appId)
        );
        QuestionVO questionVO = QuestionVO.objToVo(question);
        List<QuestionContentDTO> questionContent = questionVO.getQuestionContent();
        //2. 统计用户每个选项对应的属性的个数，如：I - 5，E - 3，T - 4，F - 2
        //初始化一个map，用户存储每个选项的计数
        Map<String, Integer> optionCountMap = new HashMap<>();
        for (QuestionContentDTO questionContentDTO : questionContent) {
            for (String choice : choices) {
                List<QuestionContentDTO.Option> options = questionContentDTO.getOptions();
                for (QuestionContentDTO.Option option : options) {
                    if (choice.equals(option.getKey())) {
                        String result = option.getResult();
                        //如果选项和用户选择的选项相同，则将对应的属性的计数加一
                        optionCountMap.put(result, optionCountMap.getOrDefault(result, 0) + 1);
                    }
                }
            }
        }
        //3. 遍历每种评分结果，计算那个结果的得分最高
        int maxScore = 0;
        ScoringResult maxScoringResult = scoringResultList.get(0);

        for (ScoringResult scoringResult : scoringResultList) {
            List<String> resultList =  JSONUtil.toList(scoringResult.getResultProp(), String.class);
            // 计算当前评分结果的分数：[I,E]=>[5,3] => 8
            int score = resultList.stream()
                    .mapToInt(prop -> optionCountMap.getOrDefault(prop, 0))
                    .sum();
            //如果当前结果的得分大于之前的最高得分，则更新最高得分和答案对象
            if (score > maxScore) {
                maxScore = score;
                maxScoringResult= scoringResult;
            }
        }
        //4. 构造返回值，填充答案对象的属性
        UserAnswer userAnswer = new UserAnswer();
        userAnswer.setAppId(appId);
        userAnswer.setAppType(app.getAppType());
        userAnswer.setScoringStrategy(app.getScoringStrategy());
        userAnswer.setChoices(JSONUtil.toJsonStr(choices));
        userAnswer.setResultId(maxScoringResult.getId());
        userAnswer.setResultName(maxScoringResult.getResultName());
        userAnswer.setResultDesc(maxScoringResult.getResultDesc());
        userAnswer.setResultPicture(maxScoringResult.getResultPicture());
        
        return userAnswer;
    }
}
